home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Utilities / Text and Speech / UUTool / uu engine / UUIntf.p < prev   
Text File  |  1991-06-12  |  11KB  |  343 lines

  1. {*}
  2. {**    Project:    uu**code engine}
  3. {**    Author:        Bernhard S. Wieser}
  4. {**    Module:        UUGlue.p}
  5. {**    Date:        5/19/91}
  6. {**    Revised:    6/1/91        L.R. suggested user allocate buffers}
  7. {**                6/8/91        L.R. suggested Pascal calling conventions}
  8. {**                            - removed table/engine globals}
  9. {**                6/11/91        Converted to Pascal by Leonard Rosenthol}
  10. {**    Version:    1.0.2}
  11. {**}
  12. {**    Preface:}
  13. {**        uu**code engine is © by Bernhard S. Wieser and Octavian Micro}
  14. {**    development, all rights reserved.  Please read the accompanying}
  15. {**    licensing agreement before use.}
  16. {**}
  17. {**    Purpose:}
  18. {**        This code should be compiled with the program using the}
  19. {**    uu**coding engine.  It loads and unloads the resource, as well as}
  20. {**    providing 'glue' to the contained routines.}
  21. {**        The 'glue' routines bind the various uu**coding functions}
  22. {**    contained in the resource file to known subroutines names, thus}
  23. {**    providing a means of easy access from a high level language.}
  24. {**    The underlying resource routines use the Pascal calling convention.}
  25. {**        The resources occupy <3K of memory.  You must make room for}
  26. {**    the buffers, except for the uuencode() and uudecode() routines which}
  27. {**    require that you specify how much (contiguous) space they will allocate.}
  28. {**        To be safe (especially with noxious INITs which invade an}
  29. {**    applications memory), allocate at least (volume buffer size)}
  30. {**    524 bytes + some so as not to unexpectedly run out of memory.}
  31. {**}
  32. {**    Conditions of use:}
  33. {**        Visible credit to Bernhard S. Wieser and Octavian Micro}
  34. {**    Development MUST be given.  Written permission MUST be obtained}
  35. {**    upon any distribution, with a licensing fee pending depending on what}
  36. {**    it is used for.}
  37. {**}
  38. {**    Algorithm:}
  39. {**        uuencoding takes 24 bit from input stream (3 bytes) and splits}
  40. {**    it into 32 bits (4 bytes) output.  Each output byte has the top 2}
  41. {**    bits clear, and can be translated into a printable character.  The}
  42. {**    traditional way is to simply add $20 (space).  uudecoding simply}
  43. {**    subtracts $20, strips the top 2 bits from input, and stuffs things }
  44. {**    back together.}
  45. {**        The encoding engine uses a translate table. Two reasons.}
  46. {**    First, its faster than bit manipulation.  Second, I can avoid}
  47. {**    some characters (like space, which some mailers despise).  This}
  48. {**    table can be changed so long as the character, when its top 2}
  49. {**    bits are stripped, equals its index into the table.}
  50. {**}
  51. {**        Example:}
  52. {**                  '`' = $60,    ' ' = $20    <- encoded}
  53. {**                  AND    $3F              $3F}
  54. {**                          ___              ___}
  55. {**                        $20              $20}
  56. {**                  SUB    $20              $20}
  57. {**                          ___              ___}
  58. {**                        $00              $00    <- decoded}
  59. {**}
  60. {**    Data Structures:}
  61. {**        Here is the resource 'UENG' 128 jump table:}
  62. {**                OFFSET    CODE}
  63. {**                   0    BRA    encode}
  64. {**                  +4    BRA    encodeOne}
  65. {**                  +8    BRA    encodeLine}
  66. {**                  +C    BRA    uuencode}
  67. {**                 +10    BRA    decode}
  68. {**                 +14    BRA    decodeOne}
  69. {**                 +18    BRA    decodeLine}
  70. {**                 +1C    BRA    uudecode}
  71. {**}
  72. {**        Resource 'HEXA' 128 is an array of 64 printable characters}
  73. {**        which equal their index when the top two bits are stripped.}
  74. {**}
  75. {**    Revisions}
  76. {**        User must now maintain the table and engine handles.  User}
  77. {**    Must also remember these are LOCKED so must be dereferenced and}
  78. {**    passed as pointers to the core routines.}
  79. {*}
  80.  
  81. UNIT UUIntf;
  82.  
  83. INTERFACE
  84.  
  85.     {Main Load/Unload routines}
  86.     FUNCTION UULoad (VAR table, engine: Handle): OSErr;
  87.     PROCEDURE UUnload (VAR table, engine: Handle);
  88.  
  89.     {Core routines for UUEncoding}
  90.     FUNCTION encodeOne (c: INTEGER; table, engine: Ptr): INTEGER;
  91.     FUNCTION encode (three, table, engine: Ptr): OSType;
  92.     FUNCTION encodeLine (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
  93.     FUNCTION uuencode (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
  94.  
  95.     {Core routines for UUDecoding}
  96.     FUNCTION decodeOne (c: INTEGER; engine: Ptr): INTEGER;
  97.     FUNCTION decode (s, engine: Ptr): OSType;
  98.     FUNCTION decodeLine (inPtr, outPtr, engine: Ptr): LONGINT;
  99.     FUNCTION uudecode (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
  100.  
  101. IMPLEMENTATION
  102.  
  103. {*}
  104. {**    UULoad}
  105. {**        Load engine, table, move them high and lock them.}
  106. {**}
  107. {**    Parameters}
  108. {**        table    handle to the encode table - passed back as a VAR}
  109. {**        engine    handle to the engine base - passed back as a VAR}
  110. {**}
  111. {**    Returns}
  112. {**        resource or memory errors}
  113. {*}
  114.     FUNCTION UULoad (VAR table, engine: Handle): OSErr;
  115.     BEGIN
  116.         UULoad := 0;
  117.         table := GetResource('HEXA', 128);
  118.         IF (table <> NIL) THEN
  119.         BEGIN
  120.             engine := GetResource('UENG', 128);
  121.             IF (engine <> NIL) THEN
  122.             BEGIN
  123.                 MoveHHi(table);
  124.                 MoveHHi(engine);
  125.                 HLock(table);
  126.                 HLock(engine);
  127.             END
  128.             ELSE
  129.             BEGIN
  130.                 UULoad := ResError;
  131.                 ReleaseResource(table);
  132.             END;
  133.         END
  134.         ELSE
  135.             UULoad := ResError;
  136.     END;
  137.  
  138. {*}
  139. {**    UUnload}
  140. {**        Get rid of the uu resources.}
  141. {**}
  142. {**    Parameters}
  143. {**        table    handle to the encode table}
  144. {**        engine    handle to the engine base}
  145. {**}
  146. {**    Returns}
  147. {**        nothing}
  148. {*}
  149.     PROCEDURE UUnload (VAR table, engine: Handle);
  150.     BEGIN
  151.         HUnlock(table);
  152.         HUnlock(engine);
  153.         ReleaseResource(table);
  154.         ReleaseResource(engine);
  155.     END;
  156.  
  157. {*                                    **}
  158. {**    The core Pascal glue routines!    **}
  159. {**                                    *}
  160.  
  161. {*}
  162. {**    encodeOne}
  163. {**        Encode one byte only, only use low 6 bits input.}
  164. {**}
  165. {**    Parameters}
  166. {**        c        the character (passed as integer)}
  167. {**        table    pointer to the encode table}
  168. {**        engine    pointer to the engine base}
  169. {**}
  170. {**    Returns}
  171. {**        the encoded character (as integer)}
  172. {*}
  173.     FUNCTION encodeOne (c: INTEGER; table, engine: Ptr): INTEGER;
  174.         FUNCTION DoIt (c: INTEGER; table, engine: Ptr): INTEGER;
  175.         INLINE
  176.             $205F, $4EA8, $0004;
  177.     BEGIN
  178.         encodeOne := DoIt(c, table, engine);
  179.     END;
  180.  
  181. {*}
  182. {**    encode}
  183. {**        Take three bytes input, return four bytes uucoded output.}
  184. {**}
  185. {**    Parameters}
  186. {**        three    pointer to an array holding at least three characters}
  187. {**        table    pointer to the encode table}
  188. {**        engine    pointer to the engine base}
  189. {**}
  190. {**    Returns}
  191. {**        four characters of encoded data in a long word}
  192. {*}
  193.     FUNCTION encode (three, table, engine: Ptr): OSType;
  194.         FUNCTION DoIt (three, table, engine: Ptr): OSType;
  195.         INLINE
  196.             $205F, $4E90;
  197.     BEGIN
  198.         encode := DoIt(three, table, engine);
  199.     END;
  200.  
  201. {*}
  202. {**    encodeLine}
  203. {**        Take 'insize' bytes from buffer 'in' and encode to buffer 'out'.}
  204. {**    The size of the encode data is returned (including length and CR).}
  205. {**    Remember, input buffer should be divisible by 3, and output size}
  206. {**    will be 4 times the quotient (plus 2 for length and CR).}
  207. {**}
  208. {**    Parameters}
  209. {**        inPtr    pointer to input buffer}
  210. {**        insize    size of input buffer}
  211. {**        outPtr    pointer to output buffer}
  212. {**        table    pointer to the encode table}
  213. {**        engine    pointer to the engine base}
  214. {**}
  215. {**    Returns}
  216. {**        length of encoded data in output buffer}
  217. {*}
  218.     FUNCTION encodeLine (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
  219.         FUNCTION DoIt (inPtr: Ptr; insize: INTEGER; outPtr, table, engine: Ptr): LONGINT;
  220.         INLINE
  221.             $205F, $4EA8, $0008;
  222.     BEGIN
  223.         encodeLine := DoIt(inPtr, inSize, outPtr, table, engine);
  224.     END;
  225.  
  226. {*}
  227. {**    uuencode}
  228. {**        Encode file 'infile' to output file 'outfile', calling}
  229. {**    'routine' as buffers are flushed.  'routine' should be NULL}
  230. {**    if there are no periodic tasks to perform.  'numbufrs' tells the}
  231. {**    engine how many input/output buffers to allocate.  An input}
  232. {**    buffer is 45 bytes long, and output buffer is 62 bytes long.}
  233. {**    Example, numbufrs = 1024 would allocate 45K+62K = 107K.}
  234. {**}
  235. {**    Parameters}
  236. {**        infile        input file's file reference number}
  237. {**        outfile        output file's "        "        "}
  238. {**        numbufrs    number of i/o buffers to use (not size of!)}
  239. {**        routine        update procedure pointer (or NIL)}
  240. {**        table        pointer to the encode table}
  241. {**        engine        pointer to the engine base}
  242. {**}
  243. {**    Returns}
  244. {**        any error encountered}
  245. {*}
  246.     FUNCTION uuencode (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
  247.         FUNCTION DoIt (infile, outfile, numbufrs: INTEGER; routine, table, engine: Ptr): OSErr;
  248.         INLINE
  249.             $205F, $4EA8, $000C;
  250.     BEGIN
  251.         uuencode := DoIt(infile, outfile, numbufrs, routine, table, engine);
  252.     END;
  253.  
  254. {*}
  255. {**    decodeOne}
  256. {**        Decode one coded character.}
  257. {**}
  258. {**    Parameters}
  259. {**        c        encoded character (integer passed)}
  260. {**        engine    pointer to the engine's base address}
  261. {**}
  262. {**    Returns}
  263. {**        the decoded character (integer)}
  264. {*}
  265.     FUNCTION decodeOne (c: INTEGER; engine: Ptr): INTEGER;
  266.         FUNCTION DoIt (c: INTEGER; engine: Ptr): INTEGER;
  267.         INLINE
  268.             $205F, $4EA8, $0014;
  269.     BEGIN
  270.         decodeOne := DoIt(c, engine);
  271.     END;
  272.  
  273. {*}
  274. {**    decode}
  275. {**        Decode 4 bytes to 3.}
  276. {**}
  277. {**    Parameters}
  278. {**        s    pointer to 4 byte array of data to decode}
  279. {**        engine    pointer to the engine's base address}
  280. {**}
  281. {**    Returns}
  282. {**        the decoded data (in the upper 8 bits of a long word)}
  283. {*}
  284.     FUNCTION decode (s, engine: Ptr): OSType;
  285.         FUNCTION DoIt (s, engine: Ptr): OSType;
  286.         INLINE
  287.             $205F, $4EA8, $0010;
  288.     BEGIN
  289.         decode := DoIt(s, engine);
  290.     END;
  291.  
  292. {*}
  293. {**    decodeLine}
  294. {**        Decode a uucoded input in 'in' to buffer 'out'.  Returns}
  295. {**    length of decoded data.}
  296. {**}
  297. {**    Parameters}
  298. {**        inPtr    pointer to an input buffer, of which first encoded}
  299. {**                character is buffer length}
  300. {**        outPtr    pointer to the buffer to contained decoded data,}
  301. {**                generally < 80 bytes is required.}
  302. {**        engine    pointer to the engine's base address}
  303. {**}
  304. {**    Returns}
  305. {**        the amount of decoded data (or buffer size if you like)}
  306. {*}
  307.     FUNCTION decodeLine (inPtr, outPtr, engine: Ptr): LONGINT;
  308.         FUNCTION DoIt (inPtr, outPtr, engine: Ptr): LONGINT;
  309.         INLINE
  310.             $205F, $4EA8, $0018;
  311.     BEGIN
  312.         decodeLine := DoIt(inPtr, outPtr, engine);
  313.     END;
  314.  
  315. {*}
  316. {**    uudecode}
  317. {**        Decode 'infile' to 'outfile', calling 'routine' on buffer flush.}
  318. {**    'bufsizes', unlike in uuencode, is the actual buffer size in bytes}
  319. {**    that you want to allocated for input and output buffers.}
  320. {**  NEVER allocate a buffer less than 10 bytes (it would be very silly).}
  321. {**    Suggested values are multiples of 524 bytes.}
  322. {**    Function returns error.}
  323. {**}
  324. {**    Parameters}
  325. {**        infile        file reference number of input (encoded) data}
  326. {**        outfile        "        "        "      of output (decoded) data}
  327. {**        bufsizes    the size in bytes for input and output buffers}
  328. {**                    to be allocated by uudecode()}
  329. {**        routine        the update procedure (or NIL if none)}
  330. {**        engine        pointer to the engine's base address}
  331. {**}
  332. {**    Returns}
  333. {**        any errors encountered}
  334. {*}
  335.     FUNCTION uudecode (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
  336.         FUNCTION DoIt (infile, outfile: INTEGER; bufsizes: LONGINT; routine, engine: Ptr): OSErr;
  337.         INLINE
  338.             $205F, $4EA8, $001C;
  339.     BEGIN
  340.         uudecode := DoIt(infile, outfile, bufsizes, routine, engine);
  341.     END;
  342.  
  343. END.